package com.gframework.mybatis.service;

import java.io.Serializable;
import java.util.Collection;

import org.springframework.lang.Nullable;

import com.gframework.mybatis.dao.IPrimaryDAO;
import com.gframework.mybatis.dao.ITableBasicDAO;
import com.gframework.mybatis.service.impl.ServiceImpl;
import com.gframework.mybatis.service.impl.TableServiceImpl;
import com.gframework.mybatis.service.impl.ViewServiceImpl;

/**
 * 基于本套mybatis框架的service通用操作父接口.
 * <p>此接口定义了dao类型必须是{@link ITableBasicDAO}和{@link IPrimaryDAO}接口子类/子接口。
 * 
 * @since 2.0.0
 * @author Ghwolf
 *
 * @see ITableService
 * @see IViewService
 * @see TableServiceImpl
 * @see ViewServiceImpl
 * @see ServiceImpl
 *
 * @param <M> 当前操作对应的dao接口类型
 * @param <K> 实体类的主键类型
 * @param <T> 实体类类型
 */
public interface IService<M extends ITableBasicDAO<T> & IPrimaryDAO<K, T>, K extends Serializable, T extends Serializable>
		extends ITableService<M, T> {
	
	/**
	 * 根据id查询一条数据，如果没有则返回null
	 * @param id 要查询的数据id，如果为null则返回null
	 * @return 如果存在数据则返回否则返回null
	 */
	@Nullable
	public T get(@Nullable K id);
	
	/**
	 * 根据id更新一个实体类
	 * @param pojo 要更新的实体类对象，必须提供主键，否则将抛出异常
	 * @return 如果更新成功返回true，无数据被更新则返回false
	 * @throws IllegalArgumentException 如果参数为null
	 */
	public boolean update(T pojo);
	
	/**
	 * 创建或修改一个对象，添加前会先根据id查询，如果有查询到数据，则更新，否则创建。
	 * <p>如果表不存在主键或数据未提供主键，则会进行保存
	 * @param pojo 准备添加或修改的对象
	 * @return 如果是添加操作，则返回true，如果是修改，则返回false
	 * @throws IllegalArgumentException 如果参数为null
	 */
	public boolean saveOrUpdate(T pojo) ;
	
	/**
	 * 根据id删除一条数据
	 * @param id 要删除的数据id，可以为null
	 * @return 删除的数据条数，如果没有数据被删除则返回0
	 */
	public int delete(@Nullable K id);
	
	/**
	 * 根据多个id删除数据
	 * @param ids 要删除的数据id，可以为null
	 * @return 删除的数据条数，如果没有数据被删除则返回0
	 */
	@SuppressWarnings("unchecked")
	public int delete(@Nullable K ... ids);
	
	/**
	 * 根据多个id删除数据
	 * @param ids 要删除的数据id，可以为null
	 * @return 删除的数据条数，如果没有数据被删除则返回0
	 */
	public int delete(@Nullable Collection<K> ids);
	

	
}
